-- 0823
我試了好幾個數字,丟進去時都沒什麼反應。自暴自棄之下,我開始亂試,其中有幾個東西丟進去的時候,開孔很快的把東西噴回來。感覺好像是有點生氣了。
一直到我放了一個空的串列 []
進去時,洞口上方的字終於變了,寫著 Sum ?
。我還注意到,當我把空串列丟進去的時候,隔壁的建築似乎微微的發亮了一下。
嗯… Sum
... 是什麼呢?
看過了 Semigroup 的法則之後,我們來思考一下有哪些東西可以算是 Semigroup:
字串是一種 Semigroup。把兩個字串相接在一起的二元運算是 ++
。
封閉律:
任兩個字串相接,結果也是個字串。
-- Haskell語法
"Haskell" ++ "Rocks" -- => "HaskellRocks"
結合律:
三個字串相接,先接哪兩個沒有差別。
-- Haskell語法
("I" ++ "like") ++ "Haskell" == "I" ++ ("like" ++ "Haskell")
-- Haskell 語法
instance Semigroup String where
(<>) = (++)
串列也是一種 Semigroup。把兩個串列相接在一起的二元運算,也是 ++
。
封閉律:
任兩個串列相接,結果也是個串列。
-- Haskell語法
[1, 2, 3] ++ [4, 5, 6] # --> [1, 2, 3, 4, 5, 6]
結合律:
三個串列相接,先接哪兩個沒有差別。
-- Haskell語法
([1, 2] ++ [3, 4]) ++ [5, 6] == [1, 2] ++ ([3, 4] ++ [5, 6])
```haskell
-- Haskell 語法
instance Semigroup [a] where
(<>) = (++)
```
很不幸的,整數不是 Semigroup。
因為整數上符合封閉律與結合律的二位運算...不只一種。而每個型別,只能有一個 typeclass 的實作(實體)。所以,必須要想辦法把它們分開。
是的。
一旦指定了是加法之後,那麼整數加法就符合了 Semigroup 的法則了。Haskell 的做法是做出一種新的型別,表示整數加法的概念。這個型別是:Sum
。
同理,整數乘法也是 Semigroup。代表整數乘法的型別叫 Product
。上述的 Sum
及這裡的 Product
,都放在 Semigroup.Data
模組下。需要另行載入才能使用。
減法可以透過改成加上負數來實現,所以視同加法。
不是。,而 不是整數,違反封閉律。這個沒辦法救。
-- Haskell 語法
[1, 2] ++ [3, 4] -- => [1, 2, 3, 4] -- 這是正常的串列串接
[1, 2] <> [3, 4] -- => [1, 2, 3, 4] -- 把串列當做 Semigroup 操作
"Hello" <> "World" -- => "HelloWorld" -- 把字串當做 Semigroup 操作
-- 有趣的部份
import Data.Semigroup
Sum 2 <> Sum 3 -- => Sum {getSum = 5} -- 把整數加法當做 Semigroup 操作
Product 2 <> Product 3 -- => Product {getProduct = 6} -- 把整數乘法當做 Semigroup 操作
這個字,由拉丁文的一半的字首:semi,加上數學上的群:group 所組成。之所以用了一半這個字,是因為要把一堆東西定義為一個群,需要符合四條法則。而半群只符合了其中兩條,故稱為半群。
當我走到盡頭的房間,看到了一樣的平台,正想著又要解謎題了的時候,卻發現那塊泛著紫色光暈的金屬板,蓋在上面。
「呃,可以…借過一下嗎?」
金屬板上,慢慢浮現了字樣:
Left $ First $ Just "go there"
「不能讓我先處理這個嗎?」
而看來它完全沒有要動的意思。
我嘆了口氣,往四周看了看,而就我左方的房間側面,看到一扇很高的門。從後方的窗戶看出去,似乎會通到…隔壁那棟建築。而從這裡看起來,它外觀已經變得非常明顯了。一回神,我發現金屬板又浮在那個門前了。
門上標識的符號是: mempty
。
[to be continue]
整數減法不是 semigroup 吧?(a-b)-c 不等於 a-(b-c)
感謝提問~
如果用「"加一個負數"來實現減法」的概念的話,(a - b) - c
跟 a - (b - c)
不是同一條式子。
第一條的 (a - b) - c
會寫成a + (-b) + (-c)
其結合律為: (a + (-b)) + (-c) = a + ((-b) + (-c))
第二條的 a - (b - c)
則是 a + (-b) + c
( c 的部份"減去一個負數"變成"加上一個正數")
其結合律為 (a + (-b)) + c = a + ((-b) + c)